import type {AxiosInstance} from 'axios'
import axios from "axios";
import type {InterceptorHooks, RequestConfig, Result} from "@/utils/axios/types.ts";


export class Request {
    private instance: AxiosInstance;
    private interceptorHooks?: InterceptorHooks;

    constructor(config: RequestConfig) {
        this.instance = axios.create(config);
        this.interceptorHooks = config.interceptorHooks;
        this.setupInterceptor();
    }

    private setupInterceptor(): void {
        // 添加对应实例独有的请求拦截器
        this.instance.interceptors.request.use(
            this.interceptorHooks?.requestInterceptor,
            this.interceptorHooks?.requestInterceptorCatch
        );

        // 添加对应实例独有的响应拦截器
        this.instance.interceptors.response.use(
            this.interceptorHooks?.responseInterceptor,
            this.interceptorHooks?.responseInterceptorCatch
        );

        // 添加所有实例都有的请求拦截器
        this.instance.interceptors.request.use(
            (config) => {
                return config;
            },
            (error) => {
                return error;
            }
        );

        // 添加所有实例都有的响应拦截器
        this.instance.interceptors.response.use(
            (response) => {
                return response;
            },
            (error) => {
                return error;
            }
        );
    }

    request<T = any>(config: RequestConfig): Promise<Result<T>> {
        return new Promise((resolve, reject) => {
            this.instance
                .request<any, Result<T>>(config)
                .then((response) => {
                    if (response.success) {
                        resolve(response);
                    } else {
                        reject(response.message);
                    }
                })
                .catch((error) => {
                    reject(error);
                });
        });
    }

    get<T = any>(
        url: string,
        config?: RequestConfig,
    ): Promise<Result<T>> {
        return this.request({
            ...config,
            url: url,
            method: "GET",
        });
    }

    post<T = any>(
        url: string,
        config?: RequestConfig,
    ): Promise<Result<T>> {
        return this.request({
            ...config,
            url: url,
            method: "POST",
        });
    }

    delete<T = any>(
        url: string,
        config?: RequestConfig,
    ): Promise<Result<T>> {
        return this.request({
            ...config,
            url: url,
            method: "DELETE",
        });
    }

    put<T = any>(
        url: string,
        config?: RequestConfig,
    ): Promise<Result<T>> {
        return this.request({
            ...config,
            url: url,
            method: "PUT",
        });
    }
}
